package com.leon.lifeenginespace.thread;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description: 唤醒和睡眠
 * @author: WT
 * @date: 2024/4/5 17:10
 * @Version 1.0
 **/
public class WaitNotify {
    // 任意时刻仅允许最多3个线程获取许可:
    final Semaphore semaphore = new Semaphore(3);

    public static void main(String[] args) throws InterruptedException {
        TaskQueue taskQueue = new TaskQueue();
        ArrayList<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(() -> {
                while (true) {
                    try {
                        String s = taskQueue.getTask();
                        System.out.println("execute task: " + s);
                    } catch (InterruptedException e) {
                        return;
                    }
                }
            });
            thread.start();
            threads.add(thread);
        }
        Thread add = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                taskQueue.addTask(i + " ");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        add.start();
        add.join();
        Thread.sleep(100);
        for (Thread t : threads) {
            t.interrupt();
        }
    }

    public void access() throws Exception {
        // 如果超过了许可数量,其他线程将在此等待:
//            semaphore.acquire();
        if (semaphore.tryAcquire(3, TimeUnit.SECONDS)) {
            try {
                // TODO:
                UUID.randomUUID().toString();
                return;
            } finally {
                //释放
                semaphore.release();
            }
        }
    }
}

class TaskQueue {

    Queue<String> queue = new LinkedList<>();


    //尝试获取锁
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();

    public synchronized void addTask(String task) {
        lock.lock();
        try {

            this.queue.add(task);
            this.notifyAll();
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public synchronized String getTask() throws InterruptedException {
        while (queue.isEmpty()) {
            this.wait();
        }
        return queue.remove();
    }

}
